package com.ruoyi.servie.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradeCreateModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeCreateRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeCreateResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.google.common.collect.Maps;
import com.ruoyi.servie.param.AliPayParams;
import com.ruoyi.servie.param.AliRefundParams;
import com.ruoyi.servie.param.AlipayNotifyParam;
import com.ruoyi.servie.service.IAliPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Slf4j
@Service
public class AliPayServiceImpl implements IAliPayService {

    @Value("${ali.ALIPAY_PUBLIC_KEY}")
    private String ALIPAY_PUBLIC_KEY;

    @Value("${ali.CHARSET}")
    private String CHARSET;

    @Value("${ali.SIGN_TYPE}")
    private String SIGN_TYPE;

    @Value("${ali.notify_url}")
    private String notify_url;

    @Autowired
    private AlipayClient alipayClient;


    @Override
    public AlipayTradeCreateResponse aliPayCreateOrder(AliPayParams aliPayParams) {
        AlipayTradeCreateRequest alipayTradeCreateRequest = new AlipayTradeCreateRequest();
        AlipayTradeCreateModel model = new AlipayTradeCreateModel();
        model.setOutTradeNo(aliPayParams.getOutTradeNo());
        model.setSubject(aliPayParams.getSubject());
        model.setTotalAmount(aliPayParams.getTotal_amount());
        model.setBody(aliPayParams.getBody());
        model.setTimeoutExpress("2m");
        model.setBuyerId(aliPayParams.getBuyUserId());

        alipayTradeCreateRequest.setBizModel(model);
        // 设置异步通知地址
        alipayTradeCreateRequest.setNotifyUrl(notify_url);
        AlipayTradeCreateResponse response = null;
        try {
            response = alipayClient.execute(alipayTradeCreateRequest);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return response;
    }

    @Override
    public void aliPayCallback(HttpServletRequest request, HttpServletResponse response, String requestUrl) throws AlipayApiException {
        Map<String, String> params = convertRequestParamsToMap(request);
        String out_trade_no = params.get("out_trade_no");
        String paramsJson = JSON.toJSONString(params);
        boolean signVerified = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY,
                CHARSET, SIGN_TYPE);
        if (signVerified) {
            log.info("支付宝回调签名认证成功");
            AlipayNotifyParam alipayNotifyParam = buildAlipayNotifyParam(params);
            if(alipayNotifyParam.getTradeStatus().equals("TRADE_SUCCESS")){
                //成功
                HashMap<String, String> reparams = Maps.newHashMap();
                reparams.put("orderNo", out_trade_no);
                reparams.put("paymentAmount", params.get("total_amount"));
                String jsonStr = JSONObject.toJSONString(reparams);
                try {
                    //调用第三方请求
                    //HttpClientResult httpClientResult = HttpClientUtil.doJsonPost(requestUrl, jsonStr);
                    if(true){
                        //如果为200才停止回调
                        response.getWriter().println("success");
                    }else{
                        log.warn("调用第三方回调失败");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    log.warn(e.toString());
                }
            }
        }else{
            log.warn("支付宝回调签名认证失败");
        }
    }

    @Override
    public AlipayTradeRefundResponse aliPayRefund(AliRefundParams aliRefundParams) {
        AlipayTradeRefundRequest alipay_request = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model=new AlipayTradeRefundModel();
        model.setOutTradeNo(aliRefundParams.getOutTradeNo());
        model.setTradeNo(aliRefundParams.getTradeNo());
        model.setRefundAmount(aliRefundParams.getRefund_amount());
        model.setRefundReason(aliRefundParams.getRefund_reason());
        alipay_request.setBizModel(model);

        AlipayTradeRefundResponse response = null;
        try{
            response = alipayClient.execute(alipay_request);
        }catch (Exception e){
            e.printStackTrace();
        }
        return response;
    }

    private AlipayNotifyParam buildAlipayNotifyParam(Map<String, String> params) {
        String json = JSON.toJSONString(params);
        return JSON.parseObject(json, AlipayNotifyParam.class);
    }

    /**
     * 将request中的参数转换成Map
     * @param request
     * @return
     */
    public static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
        Map<String, String> retMap = new HashMap<String, String>();

        Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();

        for (Map.Entry<String, String[]> entry : entrySet) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            int valLen = values.length;

            if (valLen == 1) {
                retMap.put(name, values[0]);
            } else if (valLen > 1) {
                StringBuilder sb = new StringBuilder();
                for (String val : values) {
                    sb.append(",").append(val);
                }
                retMap.put(name, sb.toString().substring(1));
            } else {
                retMap.put(name, "");
            }
        }

        return retMap;
    }

}
